Fail CI on ProseMirror schema drift - #1046
Conversation
CI: a schema-check workflow reruns npm run schema:export on every PR and push to main, failing on any diff or untracked file under schemas/prosemirror/ — the export is byte-deterministic, so drift means an editor extension change (or a TipTap bump) landed without regenerated schemas. npm ci needs TIPTAP_PRO_TOKEN and FONTAWESOME_NPM_AUTH_TOKEN repo secrets for the private TipTap Pro / Font Awesome registries. Pre-commit: a lint-staged entry regenerates and stages the schemas when staged changes touch components/Editor/extensions/, components/Comment/lib/, or the export script, so most drift never reaches CI.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
| } > .npmrc | ||
|
|
||
| - name: Install dependencies | ||
| run: npm ci |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6eea057aa1
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| env: | ||
| TIPTAP_PRO_TOKEN: ${{ secrets.TIPTAP_PRO_TOKEN }} | ||
| FONTAWESOME_NPM_AUTH_TOKEN: ${{ secrets.FONTAWESOME_NPM_AUTH_TOKEN }} |
There was a problem hiding this comment.
Keep registry tokens away from pull-request scripts
For same-repository pull requests, these job-wide secrets remain available after checkout while both npm ci and the PR-controlled schema:export script execute, so a contributor can alter prepare, the export script, or an imported module to transmit both private-registry credentials. This is not limited to explicit export code: npm documents that npm ci runs install and prepare lifecycle scripts. Install with scripts disabled and ensure the environment variables and generated .npmrc are removed before executing any code from the pull request.
Useful? React with 👍 / 👎.
| ], | ||
| "**/*.{ts,tsx}": "bash -c 'npm run type-check'" | ||
| "**/*.{ts,tsx}": "bash -c 'npm run type-check'", | ||
| "{components/Editor/extensions/**/*.{ts,tsx},components/Comment/lib/**/*.{ts,tsx},scripts/export-prosemirror-schema.ts}": "bash -c 'npm run schema:export && git add schemas/prosemirror'" |
There was a problem hiding this comment.
Stage only the generated schema files
When this hook runs while a developer has an unrelated unstaged edit under schemas/prosemirror/, such as a README change, git add schemas/prosemirror stages that edit as well and can silently include it in the extension commit. As the Git documentation notes, supplying a directory recursively adds matching files beneath it; name the two generated JSON outputs explicitly instead.
Useful? React with 👍 / 👎.




Follow-up to #1040 (stacked on its branch; GitHub will retarget to
mainwhen #1040 merges and its branch is deleted).What this adds
.github/workflows/schema-check.ymlrunsnpm ci+npm run schema:exporton every PR and push tomain, and fails if that leaves any diff or untracked file underschemas/prosemirror/. The export is byte-deterministic, so any drift means an editor extension change (or a TipTap dependency bump) landed without regenerated schemas.lint-stagedentry regenerates and stages the schemas whenever staged changes touchcomponents/Editor/extensions/,components/Comment/lib/, or the export script, so in the common case drift never reaches CI. Dependency-driven drift (e.g. a TipTap bump) is intentionally left to the CI check, since commit-time node_modules may not reflect an edited lockfile.npm ciin CI needs auth for the two private registries. Add these repo secrets (values are the same tokens as in your local.npmrc/ Vercel env):The workflow fails early with a clear message while they're missing. (Note: like any secret-dependent check, it won't work for PRs from forks — fine for this repo's branch-based flow.)
Verification
npm run schema:exporton a clean checkout of this branch: both JSON files byte-identical to what's committed (determinism + freshness confirmed).Underlinefrom the comment extensions), ran the new lint-staged entry —comment-editor.jsonwas regenerated with theunderlinemark dropped and staged automatically.🤖 Generated with Claude Code